﻿namespace WXWorkSvc.Common.Extensions;

internal static class ModelExplorerExtensions
{
 public static TagBuilder GenerateLabel(this ModelExpression modelExpression,string cssClass)
    {
        cssClass += " field-validation-valid";
        var tagLabel = new TagBuilder("label");
        tagLabel.AddCssClass(cssClass);
        tagLabel.Attributes.Add("for",modelExpression.Name.Replace(".","_").Replace("[","_").Replace("]","_"));
        tagLabel.Attributes.Add("data-valmsg-for", modelExpression.Name);
        tagLabel.Attributes.Add("data-valmsg-replace", "false");
        tagLabel.AddHtmlTooltip(modelExpression.Metadata);
        return tagLabel;
    }
    public static void GetHtmlAttributes(this ModelExpression modelExpression, out object? htmlAttributes, out string? format)
    {
        switch (modelExpression.Metadata.ModelType.Name)
        {
            case "Decimal":
            case "Int32":
            case "Int64":
                htmlAttributes = new { type = "number" };
                format = null;
                break;
            case "TimeOnly":
                format = "{0:HH:mm:ss}";
                htmlAttributes = new { type = "time" };
                break;
            case "DateOnly":
                format = "{0:yyyy-MM-dd}";
                htmlAttributes = new { type = "date" };
                break;
            case "DateTime":
                format = "{0:yyyy-MM-dd HH:mm:ss}";
                htmlAttributes = new { type = "datetime" };
                break;
            default:
                htmlAttributes = null;
                format = null;
                break;

        }

    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="modelExplorer"></param>
    /// <param name="propertyName">MetaData.PropertyName</param>
    /// <param name="itemValues"></param>
    /// <returns></returns>
    public static object GetModelValue(this ModelExplorer modelExplorer, Dictionary<string, object> itemValues, string propertyName)
    {
        if (!itemValues.TryGetValue(propertyName, out var v))
        {
            modelExplorer = modelExplorer.GetExplorerForProperty(propertyName);

            switch (modelExplorer.Metadata.ModelType.Name)
            {
                case "Boolean":

                    v = ((bool)modelExplorer.Model) ? "是" : "否";
                    break;
                case "DateOnly":
                    v = ((DateOnly)modelExplorer.Model).ToString("yyyy-MM-dd ddd");
                    break;
                default:
                    v = modelExplorer.Model;
                    break;
            }
            itemValues.Add(propertyName, v);
        }
        return v;
    }
    public static Dictionary<string, object> GetRouteValues(this ModelExplorer itemModelExplorer, Dictionary<string, object> itemValues, Dictionary<string, object> constValues, Dictionary<string, ModelExpression> routeValues, string key)
    {
        var keyPrefix = key + "-";
        var ret = constValues.Where(ii => ii.Key.StartsWith(keyPrefix, StringComparison.OrdinalIgnoreCase)).ToDictionary(ii => ii.Key.TrimStart(keyPrefix), ii => ii.Value);
        foreach (var kv in routeValues.Where(ii => ii.Key.StartsWith(keyPrefix)))
            ret.Add(kv.Key.TrimStart(keyPrefix), itemModelExplorer.GetModelValue(itemValues, kv.Value.Metadata.Name!));
        return ret;
    }
    public static Dictionary<string, object> GetRouteValues(this Dictionary<string, ModelExpression> routeValues, Dictionary<string, object> constValues, string key)
    {
        var keyPrefix = key + "-";
        var ret = constValues.Where(ii => ii.Key.StartsWith(keyPrefix, StringComparison.OrdinalIgnoreCase)).ToDictionary(ii => ii.Key.TrimStart(keyPrefix), ii => ii.Value);
        foreach (var kv in routeValues.Where(ii => ii.Key.StartsWith(keyPrefix)))
            ret.Add(kv.Key.TrimStart(keyPrefix), kv.Value.Model);
        return ret;
    }
    public static string ToFunction(this Dictionary<string, object> routeValues, string functionName)
    {
        var paras = string.Join(',', routeValues.Select(ii => "'" + ii.Value + "'"));
        return $"{functionName}({paras})";
    }
}
